package cn.xie.sdk.openai.code.review.sdk.infrastructure.git;

import cn.xie.sdk.openai.code.review.sdk.types.util.RandomStringUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author: xiaoxie
 * create: 2025-05-31 15:23
 * @BelongsProject: openai-code-review
 * @BelongsPackage: cn.xie.sdk.openai.code.review.sdk.infrastructure.git
 * description: git操作
 */
public class GitCommand {
    private final Logger log = LoggerFactory.getLogger(GitCommand.class);
    //评审代码日志的url
    private final String codeReviewLogUrl;
    //github的token
    private final String githubToken;
    //主题
    private final String project;
    //作者
    private final String author;
    //分支
    private final String branch;
    //消息
    private final String message;

    public GitCommand(String codeReviewLogUrl, String githubToken, String project, String author, String branch, String message) {
        this.codeReviewLogUrl = codeReviewLogUrl;
        this.githubToken = githubToken;
        this.project = project;
        this.author = author;
        this.branch = branch;
        this.message = message;
    }
    /**
     * @description: 代码检出
     * @author: xiaoxie
     * @date: 2025/5/31 下午3:38
     * @param: []
     * @return: java.lang.String
     **/
    public String diff() throws IOException, InterruptedException{
        // 创建一个ProcessBuilder对象，用于构建执行git log命令的进程
        // git log -1 --pretty=format:%H：获取最近一次提交的哈希值，-1表示只获取一条记录，--pretty=format:%H指定输出格式为哈希值
        ProcessBuilder logProcessBuilder = new ProcessBuilder("git", "log", "-1", "--pretty=format:%H");
        // 设置执行git log命令的工作目录为当前目录
        logProcessBuilder.directory(new File("."));
        // 启动进程，执行git log命令
        Process logProcess = logProcessBuilder.start();

        // 获取git log命令执行后的标准输出流，并包装为BufferedReader，用于读取输出内容（即最新提交的哈希值）
        BufferedReader logReader = new BufferedReader(new InputStreamReader(logProcess.getInputStream()));
        // 读取最新提交的哈希值
        String latestCommitHash = logReader.readLine();
        // 关闭BufferedReader，释放资源
        logReader.close();
        // 等待git log命令执行的进程终止
        logProcess.waitFor();

        // 创建另一个ProcessBuilder对象，用于构建执行git diff命令的进程
        // git diff commitHash^ commitHash：获取指定提交（commitHash）与父提交（commitHash^）之间的差异内容
        ProcessBuilder diffProcessBuilder = new ProcessBuilder("git", "diff", latestCommitHash + "^", latestCommitHash);
        // 设置执行git diff命令的工作目录为当前目录
        diffProcessBuilder.directory(new File("."));
        // 启动进程，执行git diff命令
        Process diffProcess = diffProcessBuilder.start();


        StringBuilder diffCode = new StringBuilder();
        // 获取git diff命令执行后的标准输出流，并包装为BufferedReader，用于按行读取diff内容
        BufferedReader diffReader = new BufferedReader(new InputStreamReader(diffProcess.getInputStream()));
        String line;
        // 循环读取每一行diff内容，并添加到StringBuilder中
        while ((line = diffReader.readLine()) != null) {
            diffCode.append(line).append("\n");
        }
        diffReader.close();

        // 等待git diff命令执行的进程终止，并获取退出码
        int exitCode = diffProcess.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException("Failed to get diff, exit code:" + exitCode);
        }

        // 返回获取到的diff内容字符串
        return diffCode.toString();
    }

    /**
     * @description: 获取评审日志的url
     * @author: xiaoxie
     * @date: 2025/5/31 下午3:52
     * @param: [recommend]
     * @return: java.lang.String
     **/
    public String getCodeReviewLogUrl(String recommend) throws Exception {
        Git git = Git.cloneRepository()
                .setURI(codeReviewLogUrl + ".git")
                .setDirectory(new File("repo"))
                .setCredentialsProvider(new UsernamePasswordCredentialsProvider(githubToken, ""))
                .call();
        // 创建分支
        String dateFolderName = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        File dateFolder = new File("repo/" + dateFolderName);
        if (!dateFolder.exists()) {
            dateFolder.mkdirs();
        }

        String fileName = project + "-" + branch + "-" + author +"-"+ new SimpleDateFormat("yyyy-MM-dd").format(new Date())
                + "-" + RandomStringUtils.generateRandomString(4) + ".md";
        File newFile = new File(dateFolder, fileName);

        try (FileWriter writer = new FileWriter(newFile)) {
            writer.write(recommend);
        }

        // 提交内容
        git.add().addFilepattern(dateFolderName + "/" + fileName).call();
        git.commit().setMessage("add code review new file" + fileName).call();
        git.push().setCredentialsProvider(new UsernamePasswordCredentialsProvider(githubToken, "")).call();

        log.info("openai-code-review git commit and push done! {}", fileName);

        return codeReviewLogUrl + "/blob/master/" + dateFolderName + "/" + fileName;

    }
    public String getProject() {
        return project;
    }

    public String getBranch() {
        return branch;
    }

    public String getAuthor() {
        return author;
    }

    public String getMessage() {
        return message;
    }

}
